package hello;
import java.util.*;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicLong;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.springframework.web.multipart.support.DefaultMultipartHttpServletRequest;
import org.springframework.validation.BindException;
import org.springframework.util.Assert;
import java.util.Map;
import java.io.*;
import java.io.BufferedReader;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import java.text.SimpleDateFormat;
import org.apache.commons.lang.RandomStringUtils;
import java.util.Date;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class GreetingController {

    private static final String template = "Hello, %s!";
    private final AtomicLong counter = new AtomicLong();

    @RequestMapping("/greeting")
    public @ResponseBody Greeting greeting(
            @RequestParam(value="name", required=false, defaultValue="World") String name) {
    	System.out.println("==== in greeting ====");
        return new Greeting(counter.incrementAndGet(),
                            String.format(template, name));
    }
    
    @RequestMapping("/user_posts")
    public @ResponseBody Greeting user_posts(
            @RequestParam(value="title", required=false, defaultValue="title_default") String title,
            @RequestParam(value="location", required=false, defaultValue="location_default") String location) {
    	System.out.println("==== LWIF DATABASE====");
    	try{
            //Database_Connection dao = new Database_Connection();
            //dao.insertIntoDatabase("",title,location,"","","");
            return null;
	   }catch(Exception e){
	}
	return null;
    }
    
    /************Checking uploading Image ***************************************/
    /****************************************************************************/
    
    @RequestMapping(value="/check_upload_image", method=RequestMethod.POST) 
    public void check_upload_image(HttpServletRequest request, HttpServletResponse response/*,
                            @RequestParam(value="username", required=false, defaultValue="user_default") String username,
                            @RequestParam(value="title", required=false, defaultValue="title_default") String title,
                            @RequestParam(value="location", required=false, defaultValue="location_default") String location,
                            @RequestParam(value="category", required=false, defaultValue="category_default") String category*/
                            )   
    			    throws Exception {
        try{
	    /********Code to get the filename of image**********************/
	    MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
	    //final Map files = multiRequest.getFileMap();
	    //System.out.println(multiRequest.getFileNames());
	
	    Iterator<String> iterator = multiRequest.getFileNames();

    	    while (iterator.hasNext()) {
                String key = (String) iterator.next();
                // create multipartFile array if you upload multiple files
                MultipartFile multipartFile =  multiRequest.getFile(key);
                String fileName=multipartFile.getOriginalFilename();
	        System.out.println(fileName);
	        String random_alpha_numeric = RandomStringUtils.randomAlphanumeric(64);
                String random_file_name = random_alpha_numeric ;
	        multipartFile.transferTo(new File(new File("/home/dhiraj/Desktop/tmp"), random_file_name));
            }    
            Map map = multiRequest.getFileMap();
            MultipartFile mfile = null;
                for (Iterator iter = map.values().iterator(); iter.hasNext();) {
                    mfile = (MultipartFile) iter.next();
                                String fileName = mfile.getOriginalFilename();
            }
//	    MultipartFile multipartFile = (MultipartFile) multiRequest.getFile("file");
//	    String fileName=multipartFile.getOriginalFilename();
//	    System.out.println(fileName);
	    /****************************************************************/
//	    String random_alpha_numeric = RandomStringUtils.randomAlphanumeric(64);
//	    String random_file_name = date + random_alpha_numeric ;
//	    multipartFile.transferTo(new File(new File("/home/dhiraj/Desktop/tmp"), random_file_name));

        }catch(Exception e){
                e.printStackTrace();
        }
        /*************************************************************************************************************/
    }
    
    /*****************************************************************************/
   
    
    /****************************************************************************/
    
    @RequestMapping(value="/upload_image", method=RequestMethod.POST) 
    public void upload_image(HttpServletRequest request, HttpServletResponse response/*,
                            @RequestParam(value="username", required=false, defaultValue="user_default") String username,
                            @RequestParam(value="title", required=false, defaultValue="title_default") String title,
                            @RequestParam(value="location", required=false, defaultValue="location_default") String location,
                            @RequestParam(value="category", required=false, defaultValue="category_default") String category*/
                            )   
    			    throws Exception {
        try{
            /*Code to verify token*/
            //String tokenString = request.getParameter("token");
            //if(verifyUser(tokenString)){
            //System.out.println("Inside Upload Image " + tokenString);
	    /***********Code to get the statuse informations ****************/        
	    String username = request.getParameter("username"); 
	    String title = request.getParameter("title"); 
	    String location = request.getParameter("location"); 
	    String category = request.getParameter("category"); 
	    String description = request.getParameter("description"); 
	    /****************************************************************/
	       
	    /********Code to get the filename of image**********************/
	    MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
	    //final Map files = multiRequest.getFileMap();
	    MultipartFile multipartFile = (MultipartFile) multiRequest.getFile("file");
	    String fileName=multipartFile.getOriginalFilename();
	    /****************************************************************/
	     
	    /*********Code to put the image in a seperate location on the harddisk*****************************************/
	    SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yy:HH:mm:SS");
	    String date = sdf.format( new Date() );
	    String random_alpha_numeric = RandomStringUtils.randomAlphanumeric(64);
	    String random_file_name = date + random_alpha_numeric ;
	    multipartFile.transferTo(new File(new File("/home/dhiraj/Desktop/tmp"), random_file_name));
	    System.out.println(random_file_name);
	    /*************************************************************************************************************/
	 
	    /*************Code to put the status information into the database *******************************************/
	    Database_Connection dao = new Database_Connection();
	    dao.insertIntoDatabase(username,title,location,random_file_name,category,description);
	    //}
	    //else{
	    //	System.out.println("User not logged in");
	    //}    
        }catch(Exception e){
                e.printStackTrace();
        }
        /*************************************************************************************************************/
    }
    
    
    @RequestMapping(value="/signup", method=RequestMethod.POST) 
    public @ResponseBody UserInformation signup(HttpServletRequest request, HttpServletResponse response)   
    			    throws Exception {

        long durationDays = 10; 
        String tokenString = "";   			    
        String name = request.getParameter("name");
        String email = request.getParameter("email");
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String birthday = request.getParameter("birthday");
        String sex = request.getParameter("sex");
        UserInformation userinfo = new UserInformation();
        System.out.println("\n" + name + " " + email + " " + username + " " + password + " " + birthday + " " + sex);
        try{
            Database_Connection dao = new Database_Connection();
            dao.signup(name,email,username,password,birthday,sex);
            System.out.println("Successfully inserted the user");
            
            /*Now we need to generate the token*/
            JWT token = new JWT();
            tokenString = token.createJsonWebToken(username,durationDays);
            
            /*Setting the user information*/
            userinfo.setUsername(username);
            userinfo.setTokenString(tokenString);
            /*****************************/
            
            System.out.println(tokenString);
            return userinfo;
           }catch(Exception e){
                e.printStackTrace();
        }
        /*If sign up was problem no toke will be returned*/
        return userinfo;
        
        
        /*************************************************************************************************************/

    }
    
    /*This method will verify that the user is authentic or not*/
    public boolean verifyUser(String tokenString) throws Exception{
        String username = "";
        /*Now we need to generate the token*/
        JWT token = new JWT();
        TokenInfo token_info = token.verifyToken(tokenString);
        username = token_info.getUserId();
        System.out.println("Username: " + username);
        
        Database_Connection dao = new Database_Connection();
        
        if (dao.getNoOfRows(username) == 1)
                return true;
        else if (dao.getNoOfRows(username) >= 1)
                throw new Exception("More than one user with the same name");
        else 
                throw new Exception("Wrong user name");        
    }
    
    //Method to return a hashmap of row values for a table
    private LinkedHashMap<String,String> getRowValues(String[] arguments){
        LinkedHashMap<String,String> row_values = new LinkedHashMap<String,String>();
    	int j = arguments.length/2 ;
        for(int i=0; i<j; i++){
        	row_values.put(arguments[i],arguments[i+j]);
        }
        return row_values;
    }
    
    
   int id_of_row;

    /***********Posting the textual nformation *******************/
    /*When we try to sign in using custom log in*/
    @RequestMapping(value="/post_textual_info", method=RequestMethod.POST) 
    public @ResponseBody String Post_Textual_Info (HttpServletRequest request, HttpServletResponse response)   
    			    throws Exception{
    			    
        String title = request.getParameter("title");   			    
        String description = request.getParameter("description");   			    
        String category = request.getParameter("category");   			    
        String location = request.getParameter("location");
        String latitude = request.getParameter("latitude");
        String longitude = request.getParameter("longitude");   			                            
        //Creating the database object to access the database
        Database_Connection dao = new Database_Connection();
        //calling the method to insert into post_text_info and passing all values 
          //and row names
        //inserting a row for post text info  
    
        id_of_row = dao.insert_into_table("post_text_info",getRowValues(new String[]{"username","title","description",
                              "user",title,description}));
        //splitting the category string into a array of strings
        String categories[] = category.split(",");                      
        //Inserting the category in category table
        for(int i=0;i<categories.length;i++){
        id_of_row = dao.insert_into_table("category",getRowValues(new String[]{"uid","category",
                                                                            String.valueOf(id_of_row),categories[i]}));
        }
        
        //splitting the category string into a array of strings
        String locations[] = location.split(",");                      
        //Inserting the category in category table
        System.out.println(latitude);
        id_of_row = dao.insert_into_table("location",getRowValues(new String[]{"uid","latitude","longitude",
                                                                            String.valueOf(id_of_row),locations[0],
                                                                            locations[1]}));
        
        return String.valueOf(id_of_row);
    }  
    
    @RequestMapping(value="/post_files", method=RequestMethod.POST) 
    public void Post_Files (HttpServletRequest request, HttpServletResponse response)   
    			    throws Exception{
    			    
        //String key = request.getParameter("key");  
            /********Code to get the filename of image**********************/
	    MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
	    //final Map files = multiRequest.getFileMap();
	    MultipartFile multipartFile = (MultipartFile) multiRequest.getFile("file");
	    String fileName=multipartFile.getOriginalFilename();
	    System.out.println("Filename " + fileName);
	    /****************************************************************/
	     
	    /*********Code to put the image in a seperate location on the harddisk*****************************************/
	    SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yy:HH:mm:SS");
	    String date = sdf.format( new Date() );
	    String random_alpha_numeric = RandomStringUtils.randomAlphanumeric(64);
	    String random_file_name = date + random_alpha_numeric ;
	    multipartFile.transferTo(new File(new File("/home/dhiraj/Desktop/tmp"), random_file_name ));
	    //System.out.println(random_file_name);
	    /*************************************************************************************************************/        
	    //Just print the contentsInserting into the database
	    Database_Connection dao = new Database_Connection();
           //calling the method to insert into post_text_info and passing all values 
              //and row names
            id_of_row = dao.insert_into_table("files",getRowValues(new String[]{
                                                                            "uid","filename","filelocation",
                                                                            String.valueOf(id_of_row),random_file_name,
                                                                            "/home/dhiraj/Desktop/tmp"}));
        
	    
	    
    }   			    
    
    
    
    /*When we try to sign in using custom log in*/
    @RequestMapping(value="/customsignin", method=RequestMethod.POST) 
    public @ResponseBody UserInformation customsignin(HttpServletRequest request, HttpServletResponse response)   
    			    throws Exception {
    	/***********Initializing the variables************/		    
        String tokenString = "";
        long durationDays = 10; 
        UserInformation userinfo = new UserInformation();
        /*************************************************/
        try{
        /*Getting the username and password from request*/
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        /**********************************************/
        
        /*Creating the database object*/
        Database_Connection dao = new Database_Connection();
        int countOfRows = dao.getNoOfRowsForPasswordAuthentication(username,password);
        
        /*Authenticating with the database*/
        if( countOfRows == 1){
            JWT token = new JWT();
            /*Generating the tolen string*/
            tokenString = token.createJsonWebToken(username,durationDays);
            
            /*Setting the user information*/
            userinfo.setUsername(username);
            userinfo.setTokenString(tokenString);
            /*****************************/
            
            System.out.println(tokenString);
            /*Returning the username  and token*/
            return userinfo;
        }
        
        else if(countOfRows == 0){
        	throw new Exception("Username and password did not match");
        }
        
        else{
        	throw new Exception("More than one username and password matched");
        }
        
        
        }catch(Exception e){
        	e.printStackTrace();
        }
        return userinfo;
        /*************************************************************************************************************/

    }
    /*When we sign up and then default sign in*/
    @RequestMapping(value="/defaultsignin", method=RequestMethod.POST) 
    public @ResponseBody String defaultsignin(HttpServletRequest request, HttpServletResponse response)   
    			    throws Exception {

        long durationDays = 10; 
        String tokenString = request.getParameter("token");
        
        try{
            if(verifyUser(tokenString)){
            	return "true";
            }
        }catch(Exception e){
                e.printStackTrace();
        }
        
        /*If unsuccessfully then return false*/
        return "false";
        
        /*************************************************************************************************************/

    }
    
    /************Download post*************************************************/
    
    @RequestMapping(value="/downloadpost", method=RequestMethod.POST) 
    public @ResponseBody UserPost downloadpost(HttpServletRequest request, HttpServletResponse response)   
    			    throws Exception {

//        String sex = request.getParameter("sex");
        UserPost post = new UserPost();
        try{
//            Database_Connection dao = new Database_Connection();
//            dao.signup(name,email,username,password,birthday,sex);
//            System.out.println("Successfully inserted the user");
            post.setUsername("user");
            post.setTitle("title for post");
            post.setDescription("description for post");
            return post;
           }catch(Exception e){
                e.printStackTrace();
        }
        /*If sign up was problem no toke will be returned*/
        return post;
        
        
        /*************************************************************************************************************/

    }
    
    /*************************************************************************/
    
    /**************Downloading image or any file for that matter ************/
    @RequestMapping(value="/downloadimage", method=RequestMethod.GET) 
    public void downloadimage(HttpServletRequest request,
        HttpServletResponse response) throws Exception {
        //int id = ServletRequestUtils.getRequiredIntParameter(request, "id");
        try{
        //Files file = this.filesService.find(id);
            String filepath = "/home/dhiraj/Desktop/tmp/image1.jpg";
	    System.out.println("Inside downloadpost");
            BufferedInputStream in  = new BufferedInputStream(new FileInputStream(filepath));
            //String mimetype = servletContext.getMimeType(fileNpath);

            //response.setBufferSize(fSize);
           // response.setContentType(mimetype); 
           // response.setHeader("Content-Disposition", "attachment; filename=\""+ fileName + "\"");
           // response.setContentLength(fSize); 
            
          FileCopyUtils.copy(org.apache.commons.io.FileUtils.readFileToByteArray(new File(filepath)), response.getOutputStream());
          //  FileCopyUtils.copy(in, response.getOutputStream());
            //in.close();
            //response.getOutputStream().flush();
            //response.getOutputStream().close(); 
        }catch(Exception e){
             e.printStackTrace();
        }
        System.out.println("Exiting");
 
    }
    
    /**********************************************************************/
    
    /********************Method for user posts ****************************/
    
    @RequestMapping(value="/get_posts", method=RequestMethod.GET) 
    public @ResponseBody String[] get_posts(HttpServletRequest request, HttpServletResponse response)   
    			    throws Exception {

        String search_location = request.getParameter("search_location");
        String search_text = request.getParameter("search_text");
        System.out.println(search_location);
        System.out.println(search_text);
        String str[]  = {"hello","how","common","go","cum","fine"};        
        /*
        try{
            if(verifyUser(tokenString)){
            	return "true";
            }
        }catch(Exception e){
                e.printStackTrace();
        }*/
        
        /*If unsuccessfully then return false*/
        return str;
        
        /*************************************************************************************************************/

    }
    
    /**********************The end****************************************/
    
    
}
